import * as THREE from 'three';
import dat from 'dat.gui';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';

export function init06(width, height) {
  // 创建一个场景，它将包含我们所有的元素，如对象，相机和灯光
  const scene = new THREE.Scene();

  // 创建一个摄像机，它定义了我们正在查看的位置
  const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);

  // 创建一个渲染器和设置大小
  const renderer = new THREE.WebGLRenderer();
  renderer.setClearColor(new THREE.Color(0x000000));
  renderer.setSize(width, height);
  renderer.shadowMap.enabled = true;

  // 创建平面
  const planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
  const planeMaterial = new THREE.MeshLambertMaterial({
    color: 0xffffff
  });
  const plane = new THREE.Mesh(planeGeometry, planeMaterial);

  // 旋转并定位平面
  plane.rotation.x = -0.5 * Math.PI;
  plane.position.x = 0;
  plane.position.y = 0;
  plane.position.z = 0;
  // 接收阴影
  plane.receiveShadow = true;
  // 将平面添加到场景中
  scene.add(plane);

  // 将相机定位并指向场景的中心
  camera.position.set(-30, 40, 30);
  camera.lookAt(scene.position);

  // 添加光源
  const ambientLight = new THREE.AmbientLight(0x3c3c3c);
  scene.add(ambientLight);

  // 为阴影添加聚光灯
  const spotLight = new THREE.SpotLight(0xffffff, 1, 180, Math.PI / 4);
  spotLight.shadow.mapSize.height = 2048;
  spotLight.shadow.mapSize.width = 2048;
  spotLight.position.set(-40, 60, -10);
  spotLight.castShadow = true;
  scene.add(spotLight);

  // 网络材料和正方体
  const material = new THREE.MeshBasicMaterial({
    color: 0x44ff44
  });
  const box = new THREE.BoxGeometry(5, 8, 3);
  const mesh = new THREE.Mesh(box, material);
  // 定位
  // mesh.position.x = 10;
  // mesh.position.y = 3;
  // mesh.position.z = 1;
  // 也可以
  mesh.position.set(10, 3, 1);
  // 第三种方式
  // mesh.position = new THREE.Vector3(10, 3, 1);
  // 旋转
  // mesh.rotation.x = 0.5 * Math.PI;
  mesh.rotation.set(0.5 * Math.PI, 0, 0);
  // mesh.rotation = new THREE.Vector3(0.5 * Math.PI, 0, 0);
  // 角度
  // const degrees = 45;
  // const inRadians = degrees * (Math.pi / 180);
  // mesh.rotation = inRadians;
  scene.add(mesh);

  // 变量控制器
  const gui = new dat.GUI();
  // 所有可控制的变量
  const controls = new (function() {
    // 缩放
    this.scaleX = 1;
    this.scaleY = 1;
    this.scaleZ = 1;
    this.scale = 1;
    // 位置
    this.positionX = 0;
    this.positionY = 4;
    this.positionZ = 0;
    // 旋转
    this.rotationX = 0;
    this.rotationY = 0;
    this.rotationZ = 0;
    // 平移
    this.translateX = 0;
    this.translateY = 0;
    this.translateZ = 0;
    // 可见
    this.visible = true;
    // 平移方法
    this.translate = function() {
      mesh.translateX(this.translateX);
      mesh.translateY(this.translateY);
      mesh.translateZ(this.translateZ);
      this.positionX = mesh.position.x;
      this.positionY = mesh.position.y;
      this.positionZ = mesh.position.z;
    };
  })();
  // 添加缩放控制组
  const guiScale = gui.addFolder('scale');
  guiScale.add(controls, 'scaleX', 0, 5);
  guiScale.add(controls, 'scaleY', 0, 5);
  guiScale.add(controls, 'scaleZ', 0, 5);
  // 添加定位控制组
  const guiPosition = gui.addFolder('position');
  const contX = guiPosition.add(controls, 'positionX', -10, 10);
  const contY = guiPosition.add(controls, 'positionY', -4, 20);
  const contZ = guiPosition.add(controls, 'positionZ', -10, 10);
  // 监听定位变更
  contX.listen();
  contX.onChange(e => {
    mesh.position.x = e;
  });
  contY.listen();
  contY.onChange(e => {
    mesh.position.y = e;
  });
  contZ.listen();
  contZ.onChange(e => {
    mesh.position.z = e;
  });
  // 添加旋转控制组
  const guiRotation = gui.addFolder('rotation');
  guiRotation.add(controls, 'rotationX', -4, 4);
  guiRotation.add(controls, 'rotationY', -4, 4);
  guiRotation.add(controls, 'rotationZ', -4, 4);
  // 添加平移控制组
  const guiTranslate = gui.addFolder('translate');
  guiTranslate.add(controls, 'translateX', -10, 10);
  guiTranslate.add(controls, 'translateY', -10, 10);
  guiTranslate.add(controls, 'translateZ', -10, 10);
  guiTranslate.add(controls, 'translate');
  // 可见控制
  gui.add(controls, 'visible');

  // 视角操作
  const orbit = new OrbitControls(camera, renderer.domElement);

  // 将呈现器的输出添加到html元素中
  document.getElementById('webgl-output').appendChild(renderer.domElement);

  // 浏览器大小自适应
  window.addEventListener('resize', onResize, false);

  render();

  function render() {
    mesh.visible = controls.visible;
    mesh.rotation.x = controls.rotationX;
    mesh.rotation.y = controls.rotationY;
    mesh.rotation.z = controls.rotationZ;
    mesh.scale.set(controls.scaleX, controls.scaleY, controls.scaleZ);
    orbit.update();
    renderer.render(scene, camera);
    requestAnimationFrame(render);
  }

  function onResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(width, height);
  }
}
